CRUD App with Mongoose - Create and Read
Lesson Objectives
- Initialize a directory
- Start express
- Create New Route
- Create Create Route
- Connect Express to Mongo
- Create Fruits Model
- Have Create Route Create data in MongoDB
- Create Index Route
- Have Index Route Render All Fruits
- Have Create Route redirect to Index After Fruit Creation
- Create Show Route
- Have Index Page Link to Show Route
- Create show.ejs
Initialize a directory
- Create a directory for the app in
student_examplesandcdinto it npm initnpm install expresstouch server.js- Edit package.json to have
"main": "server.js",
Start express
server.js
const express = require("express");
const app = express();
app.listen(3000, () => {
console.log("listening");
});
Create New Route
server.js
app.get("/fruits/new", (req, res) => {
res.send("new");
});
mkdir viewsnpm install ejstouch views/new.ejs- Create the view
views/new.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h1>New Fruit page</h1>
<form action="/fruits" method="POST">
Name: <input type="text" name="name" /><br />
Color: <input type="text" name="color" /><br />
Is Ready To Eat: <input type="checkbox" name="readyToEat" /><br />
<input type="submit" name="" value="Create Fruit" />
</form>
</body>
</html>
Render the view
server.js
app.get("/fruits/new", (req, res) => {
res.render("new.ejs");
});
Create Create Route
server.js
app.post("/fruits/", (req, res) => {
res.send("received");
});
- Use express.urlencoded in server.js:
server.js
app.use(express.urlencoded({ extended: true }));
Check to see if req.body works:
server.js
app.post("/fruits/", (req, res) => {
res.send(req.body);
});
Format data properly
server.js
app.post("/fruits/", (req, res) => {
if (req.body.readyToEat === "on") {
// if checked, req.body.readyToEat is set to 'on'
req.body.readyToEat = true;
} else {
// if not checked, req.body.readyToEat is undefined
req.body.readyToEat = false;
}
res.send(req.body);
});
Connect Express to Mongo
npm install mongoose- Inside server.js:
server.js
const mongoose = require("mongoose");
//... and then farther down the file
mongoose.connect("mongodb://localhost:27017/basiccrud", {
useNewUrlParser: true,
});
mongoose.connection.once("open", () => {
console.log("connected to mongo");
});
Create Fruits Model
mkdir modelstouch models/fruits.js- Create the fruit schema
models/fruits.js
const mongoose = require("mongoose");
const fruitSchema = new mongoose.Schema({
name: { type: String, required: true },
color: { type: String, required: true },
readyToEat: Boolean,
});
const Fruit = mongoose.model("Fruit", fruitSchema);
module.exports = Fruit;
Have Create Route Create data in MongoDB
Inside server.js:
server.js
const Fruit = require("./models/fruits.js");
//... and then farther down the file
app.post("/fruits/", async (req, res) => {
if (req.body.readyToEat === "on") {
// if checked, req.body.readyToEat is set to 'on'
req.body.readyToEat = true;
} else {
// if not checked, req.body.readyToEat is undefined
req.body.readyToEat = false;
}
try {
const fruit = await Fruit.create(req.body);
res.send(fruit);
} catch (error) {
res.send(error);
};
});
Create Index Route
server.js
app.get("/fruits", (req, res) => {
res.send("index");
});
touch views/index.ejs
views/index.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h1>Fruits index page</h1>
</body>
</html>
Render the ejs file
server.js
app.get("/fruits", (req, res) => {
res.render("index.ejs");
});
Have Index Route Render All Fruits
server.js
app.get("/fruits", async (req, res) => {
try {
const allFruits = await Fruit.find({});
res.render("index.ejs", { fruits : allFruits })
} catch (error) {
console.log(error);
};
});
Update the ejs file:
views/index.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>Fruits index page</h1>
<ul>
<% for(let i = 0; i < fruits.length; i++){ %>
<li>
The <%=fruits[i].name; %> is <%=fruits[i].color; %>.
<% if(fruits[i].readyToEat === true){ %>
It is ready to eat
<% } else { %>
It is not ready to eat
<% } %>
</li>
<% } %>
</ul>
</body>
</html>
Add a link to the create page:
views/index.ejs
<nav>
<a href="/fruits/new">Create a New Fruit</a>
</nav>
Have Create Route redirect to Index After Fruit Creation
Inside the create route
server.js
try {
const createdFruit = await Fruit.create(req.body);
res.redirect("/fruits");
} catch (error) {
res.send(error);
};
Have Index Page Link to Show Route
views/index.ejs
<li>
The
<a href="/fruits/<%= fruits[i].id %>">
<%= fruits[i].name; %>
</a>
is <%= fruits[i].color; %>.
<% if (fruits[i].readyToEat) { %>
It is ready to eat
<% } else { %>
It is not ready to eat
<% } %>
</li>
Create Show Route
server.js
app.get("/fruits/:id", async (req, res) => {
try {
const foundFruit = await Fruit.findById(req.params.id);
res.send(foundFruit);
} catch (error) {
res.send(error);
};
});
Create show.ejs
touch views/show.ejs- Add HTML
views/show.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>Fruits show page</h1>
The <%=fruit.name; %> is <%=fruit.color; %>.
<% if(fruit.readyToEat === true){ %>
It is ready to eat
<% } else { %>
It is not ready to eat
<% } %>
<nav>
<a href="/fruits">Back to Fruits Index</a>
</nav>
</body>
</html>
Render the ejs
server.js
app.get("/fruits/:id", async (req, res) => {
try {
const foundFruit = await Fruit.findById(req.params.id);
res.render("show.ejs", {
fruit: foundFruit,
});
} catch (error) {
res.send(error);
};
});